home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / aplictns / cbc.1 < prev    next >
Text File  |  1989-03-15  |  18KB  |  902 lines

  1. Path: xanth!nic.MR.NET!hal!cwjcc!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i062:  cbc - cipher block chaining encryption
  5. Message-ID: <12248@swan.ulowell.edu>
  6. Date: 15 Mar 89 20:19:41 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 891
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: uunet!mcvax!unido!altger!vyrus (David Vincenzetti)
  12. Posting-number: Volume 89, Issue 62
  13. Archive-name: applications/cbc.1
  14.  
  15. [File encoding routines.  Binary was not supplied, but a makefile was.
  16. ..Bob]
  17.  
  18. #    This is a shell archive.
  19. #    Remove everything above and including the cut line.
  20. #    Then run the rest of the file through sh.
  21. #----cut here-----cut here-----cut here-----cut here----#
  22. #!/bin/sh
  23. # shar:    Shell Archiver
  24. #    Run the following text with /bin/sh to create:
  25. #    read_me
  26. #    makefile
  27. #    cbc.h
  28. #    cbc.c
  29. #    dofile.c
  30. #    func.c
  31. # This archive created: Wed Mar 15 15:15:44 1989
  32. cat << \SHAR_EOF > read_me
  33. /* :ts=8 */
  34.  
  35. ProgramName:    Cbc (Cipher Block Chaining with DES)
  36.  
  37. Purpose:    To protect files in a real secure manner
  38.         using cryptography.
  39.  
  40. Programmer:    David Vincenzetti [vyrus@altger.UUCP]
  41.  
  42. PlagiarPolicy:    Don't use commercially!
  43.  
  44.  
  45. Cbc is simple to use: you have to provide at least one file to be
  46. encoded (if you supply the -e option or no option) or decoded (-d option).
  47. If you do not use the -i option the Ignore Mode is not enabled so the
  48. program will write the encryption key in an encoded format to ciphertext
  49. while encoding and it will check for key correctness while decoding.
  50. For istance if you crypt a file (no -i option!) with key = "hello" and try
  51. to decrypt with key = "hallo" you will get an error message telling that
  52. you are using the wrong key.
  53. I found the -i option somewhat dangerous at late night.
  54.  
  55. Cbc was written for the great Amiga PC but is surely portable everywhere
  56. (ie: in your trashcan if you print it), with a minimal work.
  57. You can copy || modify it but you *Cannot* sell or use it whithin commercial
  58. products - You must keep copyright notices too (I wanna be famous you see).
  59.  
  60. Feel free to send me comments and suggestions (please do it!!): I would
  61. REALLY appreciate if someone very experienced about cryptology would seriously
  62. test this program and send me a short note describing its weakness, bugs etc.
  63. Also, you you have written something of your own, or you got something neat
  64. send it to me. Top three topics: viruses, computer security & cryptography.
  65.  
  66. Cuse me for the shortness of this docfile but I am not good at writing in free
  67. english and I never use the dictionary...I hope that all this is intellegible
  68. to the common human..if not discard everything and send flames to /dev/null.
  69.  
  70. State [Zzzz] Mail: (Italian mail is the slower in the universe)
  71.     David Vincenzetti,
  72.     8th Street #39,
  73.     20090 Segrate (MI)
  74.         Italy
  75.  
  76. UUCP: (I hope korn (the sysop) won't close my account! Greetings Korn!!)
  77.     {elsewhere}...!uunet!mcvax!unido!altger!vyrus
  78. SHAR_EOF
  79. cat << \SHAR_EOF > makefile
  80. # :ts=8 bk=0
  81. # makefile for cbc
  82.  
  83. OBJECTS = cbc.o dofile.o func.o
  84. CFLAGS = -n
  85.  
  86. xxcbc: $(OBJECTS)
  87.     ln -o cbc -g +q $(OBJECTS) -lc
  88.  
  89. $(OBJECTS):    cbc.h
  90. SHAR_EOF
  91. cat << \SHAR_EOF > cbc.h
  92. /* cbc.h */
  93.  
  94. #include <stdio.h>
  95. #include <fcntl.h>
  96. #include <stat.h>
  97.  
  98. #define ENCRYPT        0x0001    /* encode */
  99. #define DECRYPT        0x0002    /* decode */
  100. #define IGNORE        0x0004    /* don't put & check header */
  101.  
  102. /* returns */
  103. #define OK        0
  104. #define R_ERR        1    /* read error */
  105. #define W_ERR        2    /* write error */
  106. #define BAD        3    /* dangerous failure */
  107. #define MAT_ERR        4    /* encoded key wrong/missing */
  108. #define COR_ERR        5    /* file not in proper form */
  109.  
  110. /* booleans */
  111. #define TRUE        1
  112. #define FALSE        0
  113. SHAR_EOF
  114. cat << \SHAR_EOF > cbc.c
  115. /* :ts=8 bk=0 */
  116. /* xxcbc.c */
  117.  
  118. #include    "cbc.h"
  119.  
  120. char sccsid[] = "@(#) cbc.c 1.0 dec-88 =C= by David Vincenzetti";
  121.  
  122. void main(argc, argv)
  123. int argc;
  124. char **argv;
  125. {
  126.     void bad();
  127.  
  128.     char key[8];
  129.     int optindex;
  130.  
  131.     short mode;
  132.  
  133.     if(argc < 2) bad("use: cbc [-{e|d}i] key files..");
  134.  
  135.     mode = 0;
  136.     mode |= ENCRYPT; /* encrypt by default */
  137.  
  138.     for(optindex = 1; argv[optindex][0] == '-'; optindex++) {
  139.         int option;
  140.  
  141.         option = toupper(argv[optindex][1]);
  142.         if(option == '\0' || option == '-') break;
  143.         switch(option) {
  144.             case 'E':
  145.                 mode |= ENCRYPT;
  146.                 break;
  147.             case 'D':
  148.                 mode |= DECRYPT;
  149.                 break;
  150.             case 'I':
  151.                 mode |= IGNORE;
  152.                 break;
  153.             default:
  154.                 printf("option -%c ignored\n", option);
  155.                 break;
  156.         }
  157.     }
  158.  
  159.     argv += optindex; argc -= optindex;
  160.  
  161.     /* key and/or filename is missing */
  162.     if(argc < 2) bad("too few arguments");
  163.  
  164.     /*
  165.      * copy key to buffer 
  166.      */
  167.     setmem(key, 8, 0);
  168.     strncpy(key, argv[0], 8);
  169.  
  170.     /*
  171.      * get rid of ps -f or similar
  172.      */
  173.     while(*argv[0]) *argv[0]++ = 0;
  174.     ++argv; --argc;
  175.  
  176.     /*
  177.      * set cipherment keys
  178.      */
  179.     setup(key);
  180.  
  181.     /*
  182.      * Create IV Initializing Variable
  183.      * Its secrecy and key dependency is very important
  184.      * for CBC security. I think crypt() could be used.
  185.      */
  186.     dcrypt(key, 0); /* lets scramble twice */
  187.     dcrypt(key, 0);
  188.  
  189.     /*
  190.      * main loop
  191.      */
  192.     for(optindex = 0; optindex < argc; optindex++) {
  193.         int tim;
  194.         int size;
  195.         struct stat fbuf;
  196.  
  197.         tim = time(NULL);
  198.         stat(argv[optindex], &fbuf);
  199.         size = fbuf.st_size;
  200.  
  201.         switch(dofile(argv[optindex], key, mode)){
  202.             case OK:
  203.                 printf("%s: %d bytes; elapsed: %d\n",
  204.                     argv[optindex],
  205.                     size,
  206.                     time(NULL) - tim);
  207.                 break;
  208.             case R_ERR:
  209.             case W_ERR:
  210.                 printf("R/W error; %s unencoded\n\n",
  211.                     argv[optindex]);
  212.                 break;
  213.             /*
  214.              * something shouldn't had happened HAS happened!
  215.              * We probabily lost some tmp file or..
  216.              */
  217.             case BAD:
  218.                 printf("BAD error for file %s!!\n\n",
  219.                     argv[optindex]);
  220.                 break;
  221.             /*
  222.              * we checked the file header and
  223.              * we found it mismatching
  224.              */
  225.             case MAT_ERR:
  226.                 printf("key incorrect; %s ignored\n",
  227.                     argv[optindex]);
  228.                 break;
  229.             default:
  230.                 bad("_dofile return value unknown");
  231.                 break;
  232.         }
  233.     }
  234. } /* main */
  235.  
  236. void bad(message)
  237.  
  238. char *message;
  239. {
  240.     puts(message);
  241.     exit(1);
  242. }
  243. SHAR_EOF
  244. cat << \SHAR_EOF > dofile.c
  245. /* dofile.c */
  246.  
  247. #include "cbc.h"
  248.  
  249. /*
  250.  * CBC en/decrypts a file given the IV
  251.  */
  252.  
  253. int dofile();
  254. char *mktemp();
  255. char *crypt();
  256.  
  257. int dofile(source, IV, mode)
  258. char *source, *IV;
  259. short mode;
  260. {    
  261.     char *target;        /* tmp file */
  262.     char buffer[8];        /* data buffer */
  263.     char previous[8];    /* previous data buffer */
  264.     char tmp[8];        /* yet another data buffer */
  265.     char header[11];    /* encoded key for sanity */
  266.  
  267.     int in, out;
  268.  
  269.     short first_block;    /* first block flag */
  270.     short count;        /* byte count */
  271.  
  272.     /* create tmp file */
  273.     target = mktemp("RAM:cipherXXX.XXX");
  274.     if(!*target) {
  275.         fprintf(stderr, "_mktemp failed\n");
  276.         return(BAD);
  277.     }
  278.  
  279.     if((in = open(source, O_RDONLY)) < 0){
  280.         perror(source);
  281.         return(R_ERR);
  282.     }
  283.  
  284.     if((out = open(target, O_WRONLY | O_TRUNC | O_CREAT)) < 0) {
  285.         close(out);
  286.         perror(target);
  287.         return(W_ERR);
  288.     }
  289.  
  290.     if(mode & DECRYPT && !(mode & IGNORE)) {
  291.         /*
  292.          * decryption is on, so we check for
  293.          * encoded header to match with key
  294.          */
  295.         count = read(in, header, 11);
  296.         if(count != 11 ||
  297.             strncmp(header, crypt(IV, IV) + 2, 11)) {
  298.                 close(in);
  299.                 close(out);
  300.  
  301.                 if(count < 0) {
  302.                     perror(source);
  303.                     return(R_ERR);
  304.                 }
  305.                 else return(MAT_ERR);
  306.         }
  307.     }
  308.     else if(!(mode & IGNORE)) {
  309.         /*
  310.          * write encoded key to target file
  311.          */
  312.         count = write(out, crypt(IV, IV) + 2, 11);
  313.         if(count != 11) {
  314.             close(in);
  315.             close(out);
  316.             perror(target);
  317.             return(W_ERR);
  318.         }
  319.     }
  320.  
  321.     first_block = TRUE;
  322.  
  323.     do{
  324.         /*** read block ***/
  325.         if((count = read(in, buffer, 8)) < 0) {
  326.             close(in);
  327.             close(out);
  328.             perror("_read");
  329.             return(R_ERR);
  330.         }
  331.  
  332.  
  333.         /*** decode ***/
  334.         if(mode & DECRYPT) {
  335.             if(first_block) strcopy(previous, IV, 8);
  336.             else strcopy(previous, tmp, 8);
  337.             
  338.             if(count == 8){
  339.                 strcopy(tmp, buffer, 8);
  340.                 dcrypt(buffer, 1);
  341.                 strsum(buffer, previous);
  342.             }
  343.         }
  344.         /*** encode ***/
  345.         else {
  346.             if(first_block) strcopy(previous, IV, 8);
  347.             
  348.             if(count == 8){
  349.                 strsum(buffer, previous);
  350.                 dcrypt(buffer, 0);
  351.                 strcopy(previous, buffer, 8);
  352.             }
  353.         }
  354.  
  355.         /*** cipher last short block ***/
  356.         if(count != 8){
  357.             dcrypt(previous, 0);
  358.             strsum(buffer, previous);
  359.         }    
  360.  
  361.         /*** write block ***/
  362.         if((write(out, buffer, count)) < 0) {
  363.             close(in);
  364.             close(out);
  365.             perror("_write");
  366.             return(R_ERR);
  367.         }
  368.  
  369.         first_block = FALSE;
  370.         
  371.     } while(count == 8);
  372.  
  373.     /* close & move */
  374.     if(close(in) || close(out) || mv(target, source)) {
  375.         perror("_close");
  376.         return(BAD);
  377.     }
  378.  
  379.     return(OK);
  380. }
  381. SHAR_EOF
  382. cat << \SHAR_EOF > func.c
  383. /* :ts=8 bk=0 */
  384. /* func.h */
  385.  
  386. #include "cbc.h"
  387.  
  388. void setup();    /* init cipher */
  389. void expand();    /* from bytes to bits */
  390. void compress();/* from bits to bytes */
  391. void dcrypt();    /* perform DES encryption */
  392. void strsum();    /* binary sum */
  393. int mv();    /* move files */
  394. void strcopy();    /* binary version of _strncpy */
  395.  
  396. void setup(key)
  397. char *key;
  398. {
  399.     char bits[64];
  400.     char keybuf[8];
  401.  
  402.     strcopy(keybuf, key, 8);
  403.     /****
  404.     while(*key) *key++ = 0;
  405.     ****/
  406.  
  407.     expand(keybuf, bits);
  408.     setkey(bits);
  409. }
  410.  
  411. void expand(in, out)
  412. unsigned char *in;
  413. char *out;
  414. {
  415.     int divide;
  416.     int i,j;
  417.     
  418.     for(i = 0; i < 8; i++){
  419.         divide = 1;
  420.         for(j = 0; j < 8; j++){
  421. #ifdef XENIX
  422.             *out++=(in[i] / divide) &1;
  423. #else
  424.             *out++ = (in[i] >> j) & 1;
  425. #endif
  426.             divide *=2;
  427.         }
  428.     }
  429. }
  430.  
  431. void compress(in,out)
  432. char *in;
  433. unsigned char *out;
  434. {
  435.     int temp;
  436.     int i, j;
  437.     
  438.     for(i=0; i < 8; i++){
  439.         out[i] = 0;
  440.         temp = 1;
  441.         for(j = 0; j < 8; j++){
  442. #ifdef XENIX
  443.             out[i] = out[i] + (*in++ * temp);
  444. #else
  445.             out[i] = out[i] + (*in++ << j);
  446. #endif
  447.             temp*=2;
  448.         }
  449.     }
  450. }
  451.  
  452. void dcrypt(data,decrypt)
  453. char *data;
  454. short decrypt;
  455. {
  456.     char input[8], output[8], bits[64];
  457.     
  458.     strcopy(input, data, 8);
  459.     
  460.     expand(input, bits);
  461.     encrypt(bits, decrypt);
  462.     compress(bits, output);
  463.  
  464.     strcopy(data, output, 8);
  465. }
  466.  
  467. /*
  468.  * This program implements the
  469.  * Proposed Federal Information Processing
  470.  *  Data Encryption Standard.
  471. */
  472.  
  473. static char IP[] = {
  474.     58,50,42,34,26,18,10, 2,
  475.     60,52,44,36,28,20,12, 4,
  476.     62,54,46,38,30,22,14, 6,
  477.     64,56,48,40,32,24,16, 8,
  478.     57,49,41,33,25,17, 9, 1,
  479.     59,51,43,35,27,19,11, 3,
  480.     61,53,45,37,29,21,13, 5,
  481.     63,55,47,39,31,23,15, 7,
  482. };
  483.  
  484. /*
  485.  * Final permutation, FP = IP^(-1)
  486.  */
  487. static    char    FP[] = {
  488.     40, 8,48,16,56,24,64,32,
  489.     39, 7,47,15,55,23,63,31,
  490.     38, 6,46,14,54,22,62,30,
  491.     37, 5,45,13,53,21,61,29,
  492.     36, 4,44,12,52,20,60,28,
  493.     35, 3,43,11,51,19,59,27,
  494.     34, 2,42,10,50,18,58,26,
  495.     33, 1,41, 9,49,17,57,25,
  496. };
  497.  
  498. /*
  499.  * Permuted-choice 1 from the key bits
  500.  * to yield C and D.
  501.  * Note that bits 8,16... are left out:
  502.  * They are intended for a parity check.
  503.  */
  504. static    char    PC1_C[] = {
  505.     57,49,41,33,25,17, 9,
  506.      1,58,50,42,34,26,18,
  507.     10, 2,59,51,43,35,27,
  508.     19,11, 3,60,52,44,36,
  509. };
  510.  
  511. static    char    PC1_D[] = {
  512.     63,55,47,39,31,23,15,
  513.      7,62,54,46,38,30,22,
  514.     14, 6,61,53,45,37,29,
  515.     21,13, 5,28,20,12, 4,
  516. };
  517.  
  518. /*
  519.  * Sequence of shifts used for the key schedule.
  520. */
  521. static    char    shifts[] = {
  522.     1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
  523. };
  524.  
  525. /*
  526.  * Permuted-choice 2, to pick out the bits from
  527.  * the CD array that generate the key schedule.
  528.  */
  529. static    char    PC2_C[] = {
  530.     14,17,11,24, 1, 5,
  531.      3,28,15, 6,21,10,
  532.     23,19,12, 4,26, 8,
  533.     16, 7,27,20,13, 2,
  534. };
  535.  
  536. static    char    PC2_D[] = {
  537.     41,52,31,37,47,55,
  538.     30,40,51,45,33,48,
  539.     44,49,39,56,34,53,
  540.     46,42,50,36,29,32,
  541. };
  542.  
  543. /*
  544.  * The C and D arrays used to calculate the key schedule.
  545.  */
  546.  
  547. static char    C[28];
  548. static    char    D[28];
  549. /*
  550.  * The key schedule.
  551.  * Generated from the key.
  552.  */
  553. static    char    KS[16][48];
  554.  
  555. /*
  556.  * The E bit-selection table.
  557.  */
  558. static    char    E[48];
  559. static    char    e[] = {
  560.     32, 1, 2, 3, 4, 5,
  561.      4, 5, 6, 7, 8, 9,
  562.      8, 9,10,11,12,13,
  563.     12,13,14,15,16,17,
  564.     16,17,18,19,20,21,
  565.     20,21,22,23,24,25,
  566.     24,25,26,27,28,29,
  567.     28,29,30,31,32, 1,
  568. };
  569.  
  570. /*
  571.  * Set up the key schedule from the key.
  572.  */
  573.  
  574. setkey(key)
  575. char *key;
  576. {
  577.     register i, j, k;
  578.     int t;
  579.  
  580.     /*
  581.      * First, generate C and D by permuting
  582.      * the key.  The low order bit of each
  583.      * 8-bit char is not used, so C and D are only 28
  584.      * bits apiece.
  585.      */
  586.     for (i=0; i<28; i++) {
  587.         C[i] = key[PC1_C[i]-1];
  588.         D[i] = key[PC1_D[i]-1];
  589.     }
  590.     /*
  591.      * To generate Ki, rotate C and D according
  592.      * to schedule and pick up a permutation
  593.      * using PC2.
  594.      */
  595.     for (i=0; i<16; i++) {
  596.         /*
  597.          * rotate.
  598.          */
  599.         for (k=0; k<shifts[i]; k++) {
  600.             t = C[0];
  601.             for (j=0; j<28-1; j++)
  602.                 C[j] = C[j+1];
  603.             C[27] = t;
  604.             t = D[0];
  605.             for (j=0; j<28-1; j++)
  606.                 D[j] = D[j+1];
  607.             D[27] = t;
  608.         }
  609.         /*
  610.          * get Ki. Note C and D are concatenated.
  611.          */
  612.         for (j=0; j<24; j++) {
  613.             KS[i][j] = C[PC2_C[j]-1];
  614.             KS[i][j+24] = D[PC2_D[j]-28-1];
  615.         }
  616.     }
  617.  
  618.     for(i=0;i<48;i++)
  619.         E[i] = e[i];
  620. }
  621.  
  622. /*
  623.  * The 8 selection functions.
  624.  * For some reason, they give a 0-origin
  625.  * index, unlike everything else.
  626.  */
  627. static    char    S[8][64] = {
  628.     14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
  629.      0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
  630.      4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
  631.     15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
  632.  
  633.     15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
  634.      3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
  635.      0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
  636.     13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
  637.  
  638.     10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
  639.     13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
  640.     13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
  641.      1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
  642.  
  643.      7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
  644.     13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
  645.     10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
  646.      3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
  647.  
  648.      2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
  649.     14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
  650.      4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
  651.     11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
  652.  
  653.     12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
  654.     10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
  655.      9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
  656.      4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
  657.  
  658.      4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
  659.     13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
  660.      1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
  661.      6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
  662.  
  663.     13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
  664.      1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
  665.      7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
  666.      2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
  667. };
  668.  
  669. /*
  670.  * P is a permutation on the selected combination
  671.  * of the current L and key.
  672.  */
  673. static    char    P[] = {
  674.     16, 7,20,21,
  675.     29,12,28,17,
  676.      1,15,23,26,
  677.      5,18,31,10,
  678.      2, 8,24,14,
  679.     32,27, 3, 9,
  680.     19,13,30, 6,
  681.     22,11, 4,25,
  682. };
  683.  
  684. /*
  685.  * The current block, divided into 2 halves.
  686.  */
  687. static    char    L[32], R[32];
  688. static    char    tempL[32];
  689. static    char    f[32];
  690.  
  691. /*
  692.  * The combination of the key and the input, before selection.
  693.  */
  694. static    char    preS[48];
  695.  
  696. /*
  697.  * The payoff: encrypt a block.
  698.  */
  699.  
  700. encrypt(block, edflag)
  701. char *block;
  702. int edflag;
  703. {
  704.     int i, ii;
  705.     register t, j, k;
  706.  
  707.     /*
  708.      * First, permute the bits in the input
  709.      */
  710.     for (j=0; j<64; j++)
  711.         L[j] = block[IP[j]-1];
  712.     /*
  713.      * Perform an encryption operation 16 times.
  714.      */
  715.     for (ii=0; ii<16; ii++) {
  716.         /*
  717.          * Encrypts if edflag is null,
  718.          * decrypts otherwise.. by David Vincenzetti 4-Sep-88 :-)
  719.          * Paint paint...it was an hard word to get these sources!
  720.          */
  721.         if(!edflag)
  722.             i = ii;         /* encrypts */
  723.         else
  724.             i=15-ii;        /* decrypts */
  725.         /*
  726.          * Save the R array,
  727.          * which will be the new L.
  728.          */
  729.         for (j=0; j<32; j++)
  730.             tempL[j] = R[j];
  731.         /*
  732.          * Expand R to 48 bits using the E selector;
  733.          * exclusive-or with the current key bits.
  734.          */
  735.         for (j=0; j<48; j++)
  736.             preS[j] = R[E[j]-1] ^ KS[i][j];
  737.         /*
  738.          * The pre-select bits are now considered
  739.          * in 8 groups of 6 bits each.
  740.          * The 8 selection functions map these
  741.          * 6-bit quantities into 4-bit quantities
  742.          * and the results permuted
  743.          * to make an f(R, K).
  744.          * The indexing into the selection functions
  745.          * is peculiar; it could be simplified by
  746.          * rewriting the tables.
  747.          */
  748.         for (j=0; j<8; j++) {
  749.             t = 6*j;
  750.             k = S[j][(preS[t+0]<<5)+
  751.                 (preS[t+1]<<3)+
  752.                 (preS[t+2]<<2)+
  753.                 (preS[t+3]<<1)+
  754.                 (preS[t+4]<<0)+
  755.                 (preS[t+5]<<4)];
  756.             t = 4*j;
  757.             f[t+0] = (k>>3)&01;
  758.             f[t+1] = (k>>2)&01;
  759.             f[t+2] = (k>>1)&01;
  760.             f[t+3] = (k>>0)&01;
  761.         }
  762.         /*
  763.          * The new R is L ^ f(R, K).
  764.          * The f here has to be permuted first, though.
  765.          */
  766.         for (j=0; j<32; j++)
  767.             R[j] = L[j] ^ f[P[j]-1];
  768.         /*
  769.          * Finally, the new L (the original R)
  770.          * is copied back.
  771.          */
  772.         for (j=0; j<32; j++)
  773.             L[j] = tempL[j];
  774.     }
  775.     /*
  776.      * The output L and R are reversed.
  777.      */
  778.     for (j=0; j<32; j++) {
  779.         t = L[j];
  780.         L[j] = R[j];
  781.         R[j] = t;
  782.     }
  783.     /*
  784.      * The final output
  785.      * gets the inverse permutation of the very original.
  786.      */
  787.     for (j=0; j<64; j++)
  788.         block[j] = L[FP[j]-1];
  789. }
  790.  
  791. char *
  792. crypt(pw,salt)
  793. char *pw;
  794. char *salt;
  795. {
  796.     register i, j, c;
  797.     int temp;
  798.     static char block[66], iobuf[16];
  799.  
  800.     for(i=0; i<66; i++)
  801.         block[i] = 0;
  802.     for(i=0; (c= *pw) && i<64; pw++){
  803.         for(j=0; j<7; j++, i++)
  804.             block[i] = (c>>(6-j)) & 01;
  805.         i++;
  806.     }
  807.     
  808.     setkey(block);
  809.     
  810.     for(i=0; i<66; i++)
  811.         block[i] = 0;
  812.  
  813.     for(i=0;i<2;i++){
  814.         c = *salt++;
  815.         iobuf[i] = c;
  816.         if(c>'Z') c -= 6;
  817.         if(c>'9') c -= 7;
  818.         c -= '.';
  819.         for(j=0;j<6;j++){
  820.             if((c>>j) & 01){
  821.                 temp = E[6*i+j];
  822.                 E[6*i+j] = E[6*i+j+24];
  823.                 E[6*i+j+24] = temp;
  824.                 }
  825.             }
  826.         }
  827.     
  828.     for(i=0; i<25; i++)
  829.         encrypt(block,0);
  830.     
  831.     for(i=0; i<11; i++){
  832.         c = 0;
  833.         for(j=0; j<6; j++){
  834.             c <<= 1;
  835.             c |= block[6*i+j];
  836.             }
  837.         c += '.';
  838.         if(c>'9') c += 7;
  839.         if(c>'Z') c += 6;
  840.         iobuf[i+2] = c;
  841.     }
  842.     iobuf[i+2] = 0;
  843.     if(iobuf[1]==0)
  844.         iobuf[1] = iobuf[0];
  845.     return(iobuf);
  846. }
  847.  
  848. void strsum(one, two)
  849. char *one, *two;
  850. {
  851.     short i;
  852.     
  853.     for(i=0; i < 8; i++)
  854.         one[i] = one[i] ^ two[i];
  855. }
  856.  
  857. int mv(from,to)
  858. char *from, *to;
  859. {
  860.     int in, out, len;
  861.     char block[512];
  862.     
  863.     if((in = open(from, O_RDONLY)) < 0) {
  864.         perror(from);
  865.         return(R_ERR);
  866.     }
  867.     if((out = open(to, O_WRONLY | O_CREAT | O_TRUNC)) < 0) {
  868.         close(in);
  869.         perror(to);
  870.         return(W_ERR);
  871.     }
  872.     
  873.     do{
  874.         len = read(in, block, 512);
  875.         write(out, block, len);
  876.     } while (len == 512);
  877.     
  878.     if(close(in) || close(out) ||
  879.         unlink(from)) {
  880.             perror("_unlink");
  881.             return(BAD);
  882.     }
  883.  
  884.     return(OK);
  885. }
  886.  
  887. void strcopy(to, from, len)
  888. unsigned char *from, *to;
  889. int len;
  890. {
  891.     while(len > 0) {
  892.         *to++ = *from++;
  893.         --len;
  894.     }
  895. }
  896. SHAR_EOF
  897. #    End of shell archive
  898. exit 0
  899. -- 
  900. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  901. Have five nice days.
  902.